﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices.Automation;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Practices.Composite.Presentation.Commands;
using ReflectionIT.Silverlight.ReportLibrary;
using TelecoSystems.Modules.Products.Views;
using TelecoSystems.Web.Models;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using System.ComponentModel;

namespace TelecoSystems.Modules.Products.ViewModels {
    public partial class ProductsBrowseViewModel {
        #region SubmitChanges
        public DelegateCommand<object> SubmitChangesCommand { get; set; }
        
        void SubmitChanges(object o) {
            IsBusy = true;
            if (o != null)
                _variantsCtx.SubmitChanges(SubmitChangesCompleted, null);
            else                
                _productsCtx.SubmitChanges(SubmitChangesCompleted, null);
        }
        bool CanSubmitChanges(object o) {
            return _productsCtx.HasChanges || ((ProductDetail != null) ? ProductDetail.HasChanges : false);
        }
        #endregion
        
        #region RejectChanges
        public DelegateCommand<object> RejectChangesCommand { get; set; }
        void RejectChanges(object o) {
            _productsCtx.RejectChanges();
        }
        bool CanRejectChanges(object o) {
            return _productsCtx.HasChanges || ((ProductDetail != null) ? ProductDetail.HasChanges : false);
        } 
        #endregion

        #region EditVariant
        public DelegateCommand<object> EditVariantCommand { get; set; }
        void EditVariant(object o) {
            ChildWindow win = new ChildWindow();
            win.Title = "Edit Variant";

            EditVariantView editView = new EditVariantView(new EditVariantViewModel(_productsCtx, this, win));

            win.Content = editView;
            win.HasCloseButton = false;
            win.Show();

            win.Closed += (s, e) => {
                NotifyPropertyChanged("ProductDetail");
                NotifyPropertyChanged("ProductDetail.Variants");
            };
        }
        bool CanEditVariant(object o) {
            return VariantDetail != null;
        } 
        #endregion

        #region EditVariant
        public DelegateCommand<object> AddVariantCommand { get; set; }
        void AddVariant(object o) {
            VariantDetail = new Variant() {
                ProductID = productDetail.Id
            };
            _variantsCtx.Variants.Add(VariantDetail);
            NotifyPropertyChanged("ProductDetail");
            ProductDetail.ToString();

            if (EditVariantCommand.CanExecute(null))
                EditVariantCommand.Execute(null);
        }
        bool CanAddVariant(object o) {
            return true;
            //return productDetail != null;
        } 
        #endregion

        #region DeleteVariant
        public DelegateCommand<object> DeleteVariantCommand { get; set; }
        void DeleteVariant(object o) {
            productDetail.Variants.Remove(_variantDetail);
            NotifyPropertyChanged("ProductDetail");
        }
        bool CanDeleteVariant(object o) {
            return true;
            //return _variantDetail != null;
        } 
        #endregion

        #region Export
        public DelegateCommand<string> ExportCommand { get; set; }
        void Export(string type) {
            switch (type) {
                case "Excel": ExportToExcel(); break;
                case "XML": ExportToXML(); break;
            }
        }
        private void ExportToExcel() {
            if (!App.Current.IsRunningOutOfBrowser) {
                var dialog = new SaveFileDialog();

                dialog.DefaultExt = "*.xml";
                dialog.Filter = "Excel Xml (*.xml)|*.xml|All files (*.*)|*.*";

                if (dialog.ShowDialog() ?? false) {
                    Stream fileStream = dialog.OpenFile();

                    var s = Application.GetResourceStream(new Uri("/TelecoSystems.Modules.Products;component/Assets/Templates/ExcelTemplate.xml", UriKind.Relative));
                    var sr = new StreamReader(s.Stream);

                    var sw = new StreamWriter(fileStream);
                    while (!sr.EndOfStream) {
                        var line = sr.ReadLine();
                        if (line.Trim() == "***") break;
                        sw.WriteLine(line);
                    }

                    foreach (Product p in Products) {
                        sw.WriteLine("<Row>");
                        sw.WriteLine("<Cell><Data ss:Type=\"Number\">{0}</Data></Cell>", p.Id);
                        sw.WriteLine("<Cell><Data ss:Type=\"String\">{0}</Data></Cell>", p.Name);
                        sw.WriteLine("<Cell><Data ss:Type=\"String\">{0}</Data></Cell>", p.Description);
                        sw.WriteLine("<Cell><Data ss:Type=\"String\">{0}</Data></Cell>", p.DateCreated.ToShortDateString());
                        sw.WriteLine("</Row>");
                    }
                    while (!sr.EndOfStream) {
                        sw.WriteLine(sr.ReadLine());
                    }

                    sw.Close();
                }
            } else {
                dynamic excel = AutomationFactory.CreateObject("Excel.Application");
                excel.Visible = true;
                excel.Workbooks.Add();
                dynamic workbook = excel.Workbooks[1];
                dynamic sheet = excel.ActiveSheet;

                sheet.Cells[1, 1].Value2 = "Id";
                sheet.Cells[1, 2].Value2 = "Name";
                sheet.Cells[1, 3].Value2 = "Description";
                sheet.Cells[1, 4].Value2 = "Date Created";
                sheet.Cells[1, 5].Value2 = "Price";
                int row = 2;
                foreach (Product p in Products) {
                    sheet.Cells[row, 1].Value2 = p.Id;
                    sheet.Cells[row, 2].Value2 = p.Name;
                    sheet.Cells[row, 3].Value2 = p.Description;
                    sheet.Cells[row, 4].Value2 = p.DateCreated.ToShortDateString();
                    row++;
                    sheet.Cells[row, 1].Value2 = "Product Variants";
                    row++;
                    foreach (Variant v in p.Variants) {
                        sheet.Cells[row, 1].Value2 = v.Id;
                        sheet.Cells[row, 2].Value2 = v.Name;
                        sheet.Cells[row, 3].Value2 = v.Description;
                        sheet.Cells[row, 4].Value2 = v.DateCreated.ToShortDateString();
                        sheet.Cells[row, 5].Value2 = v.Price;
                        row++;
                    }
                    row++;
                }
            }
        }        
        #endregion

        #region Print
        public DelegateCommand<object> PrintCommand { get; set; }
        void Print(object o) {
            ReportDocument doc = new ReportDocument() {
                Title = "Produkty",
                SubTitle = "Produkty spoločnosti TelecoSystems",
                PageText = "Strana ",
                DateText = "Dátum "
            };

            List<string> headers = new List<string>() { "Názov", "Popis", "Vytvorený dňa", "Cena" };
            List<int> colWidth = new List<int>() { 130, 320, 100, 100 };

            //Print StackPanel row of headers
            Color HEADER_COLOR = Color.FromArgb(255, 215, 235, 251);
            StackPanel panel = new StackPanel() { Orientation = Orientation.Horizontal, Background = new SolidColorBrush(HEADER_COLOR) };
            foreach (string header in headers) {
                panel.Children.Add(new TextBlock() {
                    Text = header,
                    FontSize = 12,
                    Width = colWidth[headers.IndexOf(header)],
                    Margin = new Thickness(5)
                });
            }
            doc.Paragraphs.Add(panel);

            //Print StackPanel rows of products and variants
            Color BASE_COLOR = Color.FromArgb(100, HEADER_COLOR.R, HEADER_COLOR.G, HEADER_COLOR.B);
            foreach (Product p in Products) {
                //Print StackPanel row of product
                panel = new StackPanel() {
                    Orientation = Orientation.Horizontal,
                    Background = new SolidColorBrush(BASE_COLOR)
                };
                List<string> values = new List<string>() { p.Name, p.Description, p.DateCreated.ToShortDateString() };
                foreach (string value in values) {
                    panel.Children.Add(new TextBlock() {
                        Text = value,
                        FontSize = 10,
                        Width = colWidth[values.IndexOf(value)],
                        Margin = new Thickness(5),
                        FontWeight = (values.IndexOf(value) == 0) ? FontWeights.Bold : FontWeights.Normal
                    });
                }
                doc.Paragraphs.Add(panel);

                //Print StackPanel rows of product's variants
                foreach (Variant v in p.Variants) {
                    panel = new StackPanel() {
                        Orientation = Orientation.Horizontal
                    };

                    values = new List<string>() { v.Name, v.Description, v.DateCreated.ToShortDateString(), string.Format("{0:0.00}", v.Price) + " €" };
                    foreach (string value in values) {
                        panel.Children.Add(new TextBlock() {
                            Text = value,
                            FontSize = 9,
                            Foreground = new SolidColorBrush(Color.FromArgb(180, 0, 0, 0)),
                            TextWrapping = System.Windows.TextWrapping.Wrap,
                            Width = colWidth[values.IndexOf(value)],
                            Margin = new Thickness(5),
                        });
                    }
                    doc.Paragraphs.Add(panel);
                }
            }

            doc.Print();
        } 
        #endregion
    }
}
